#include "threadpool.h"
#include "libasynlog/asynlog.h"

namespace threadpool {
    ThreadPool::ThreadPool(size_t threads)
    {
        if (enable_log_)
            LOG_APP_TP("{0} thread size : {1}") << __FUNCTION__ << threads << asynlog::endl();
        for (size_t i = 0; i < threads; ++i) {
            workers_.emplace_back(Worker(this));
        }
        for (auto& worker : workers_) {
            worker.Start();
        }
    }

    void ThreadPool::SetEnableLog(bool enable) {
        if (enable_log_ == enable)
            return;
        enable_log_ = enable;
        if (enable_log_){
            LOG_APP_TP("{0} thread size : {1}") << __FUNCTION__ << workers_.size() << asynlog::endl();
        }
    }

    int64_t ThreadPool::PushTask(const TaskClosure& task) {
        TaskPtr pTask = std::make_unique<Task>(task);
        int64_t taskId = task_queue_.push_back(pTask);
        if (taskId > 0) {
            condition_.notify_one();
        }
        if (enable_log_)
            LOG_PRO_TP("{0} taskId : {1}, queue len : {2}") << __FUNCTION__ << taskId << task_queue_.GetQueueLen() << asynlog::endl();
        return taskId;
    }

    TaskPtr ThreadPool::PopTask(int64_t taskId) {
        return task_queue_.pop(taskId);
    }

    ThreadPool::~ThreadPool()
    {
        if (enable_log_)
            LOG_APP_TP("{0}") << __FUNCTION__ << asynlog::endl();
        Close();
        workers_.clear();
    }

    void ThreadPool::WaitForAllWorkStop() {
        while (true)
        {
            bool all_worker_stoped = true;
            for (Worker& worker : workers_) {
                if (worker.IsRunning()) {
                    all_worker_stoped = false;
                    break;
                }
            }
            if (all_worker_stoped) {
                break;
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(200));
        }
    }
}






